/*
 * Copyright 2007-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.ymate.platform.examples.controller;

import net.ymate.framework.core.util.WebUtils;
import net.ymate.framework.webmvc.WebResult;
import net.ymate.platform.core.YMP;
import net.ymate.platform.core.util.UUIDUtils;
import net.ymate.platform.examples.base.Constants;
import net.ymate.platform.examples.base.UserSessionBean;
import net.ymate.platform.examples.model.User;
import net.ymate.platform.persistence.Fields;
import net.ymate.platform.persistence.jdbc.annotation.Transaction;
import net.ymate.platform.persistence.jdbc.query.IDBLocker;
import net.ymate.platform.validation.annotation.VField;
import net.ymate.platform.validation.validate.VCompare;
import net.ymate.platform.validation.validate.VEmail;
import net.ymate.platform.validation.validate.VRequried;
import net.ymate.platform.webmvc.annotation.Controller;
import net.ymate.platform.webmvc.annotation.RequestMapping;
import net.ymate.platform.webmvc.annotation.RequestParam;
import net.ymate.platform.webmvc.base.Type;
import net.ymate.platform.webmvc.context.WebContext;
import net.ymate.platform.webmvc.view.IView;
import net.ymate.platform.webmvc.view.View;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;

/**
 * 用户管理控制器
 *
 * @author 刘镇 (suninformation@163.com) on 16/3/12 下午9:55
 * @version 1.0
 */
@Controller
@RequestMapping("/api")
@Transaction
public class UserController {

    /**
     * 执行用户登录逻辑
     *
     * @param email     用户登录邮箱
     * @param password  登录密码
     * @param returnUrl 重定向URL地址
     * @return 返回执行结果视图对象
     * @throws Exception 任何可能发生的异常
     */
    @RequestMapping(value = "/login", method = Type.HttpMethod.POST)
    @Transaction
    public IView __doLogin(@VRequried
                           @VEmail
                           @VField(label = "form_item.email")
                           @RequestParam String email,

                           @VRequried
                           @VField(label = "form_item.password")
                           @RequestParam String password,

                           @RequestParam("redirect_url") String returnUrl) throws Exception {

        // 通过登录邮箱和密码查询用户记录
        User _user = User.builder()
                .email(email)
                .password(DigestUtils.md5Hex(email + password))
                .build().findFirst(Fields.create(User.FIELDS.ID)
                        .add(User.FIELDS.PHOTO)
                        .add(User.FIELDS.NICKNAME)
                        .add(User.FIELDS.IS_BLACKLISTED)
                        .add(User.FIELDS.IS_DISABLED)
                        .add(User.FIELDS.LAST_MODIFY_TIME), IDBLocker.MYSQL);

        YMP _owner = WebContext.getContext().getOwner().getOwner();
        // 若用户记录存在
        if (_user != null) {
            // 判断是否被锁定或黑名单
            if (Constants.BOOL_TRUE.equals(_user.getIsDisabled())
                    || Constants.BOOL_TRUE.equals(_user.getIsBlacklisted())) {
                // 返回错误提示: 用户已被锁定或黑名单, 请与网站管理员联系!
                return WebResult.CODE(1002).msg(WebUtils.messageWithTemplate(_owner, WebUtils.i18nStr(_owner, Constants.I18N_1002_USER_LOCKED_OR_BLACKLISTED))).toJSON();
            }
            // 更新记录最后修改时间
            User.builder()
                    .id(_user.getId())
                    .lastModifyTime(System.currentTimeMillis())
                    .build().update(Fields.create(User.FIELDS.LAST_MODIFY_TIME));
            // 创建新的用户会话对象
            UserSessionBean.create(_user.getId(), email);
            //
            if (StringUtils.isBlank(returnUrl)) {
                returnUrl = WebUtils.buildURL(WebContext.getRequest(), "dashboard", true);
            }
            // 返回成功
            return WebResult.SUCCESS().dataAttr("redirect_url", returnUrl).toJSON();
        }
        // 返回错误提示: 用户不存在或密码错误
        return WebResult.CODE(1001).msg(WebUtils.messageWithTemplate(_owner, WebUtils.i18nStr(_owner, Constants.I18N_1001_USER_NOT_EXIST_OR_PWD_ERROR))).toJSON();
    }

    /**
     * 执行新用户注册逻辑
     *
     * @param email           新用户邮箱地址
     * @param password        登录密码
     * @param confirmPassword 确认登录密码
     * @return 返回执行结果视图对象
     * @throws Exception 任何可能发生的异常
     */
    @RequestMapping(value = "/signup", method = Type.HttpMethod.POST)
    @Transaction
    public IView __doSignup(@VRequried
                            @VEmail
                            @VField(label = "form_item.email")
                            @RequestParam String email,

                            @VRequried
                            @VField(label = "form_item.password")
                            @RequestParam String password,

                            @VRequried
                            @VCompare(with = "password", withLabel = "form_item.password")
                            @VField(label = "form_item.confirm_password")
                            @RequestParam("confirm_password") String confirmPassword) throws Exception {

        YMP _owner = WebContext.getContext().getOwner().getOwner();
        // 检查用户邮箱地址是已可以注册
        User _user = User.builder().email(email).build().findFirst(Fields.create(User.FIELDS.ID));
        // 若记录已存在
        if (_user != null) {
            // 返回错误提示: 用户邮箱地址已存在
            return WebResult.CODE(1003).msg(WebUtils.messageWithTemplate(_owner, WebUtils.i18nStr(_owner, Constants.I18N_1003_USER_EMAIL_EXIST))).toJSON();
        }
        // 创建新用户记录
        User.builder()
                .id(UUIDUtils.UUID())
                .email(email)
                .password(DigestUtils.md5Hex(email + password))
                .createTime(System.currentTimeMillis())
                .build().save();
        // 返回成功
        return WebResult.SUCCESS()
                .dataAttr("redirect_url", WebUtils.buildURL(WebContext.getRequest(), "login", true)).toJSON();
    }

    /**
     * @return 退出登录并返回登录视图
     */
    @RequestMapping("/logout")
    public IView __doLogout() {
        WebContext.getRequest().getSession().invalidate();
        return View.redirectView(WebUtils.buildURL(WebContext.getRequest(), "login", true));
    }
}
